home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Devices and Hardware / Drivers / Load PCI Driver / Load PCI Driver.c < prev    next >
Encoding:
Text File  |  2000-09-28  |  15.0 KB  |  517 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        Load PCI Driver.c
  3.  
  4.     Contains:    Load PCI Driver Sample,This Code loads Wayne Flansburg PCI 'ndrv'
  5.                 so you can see it load without having to have a PCI card installed.
  6.                 This requires the PCI interfaces and libraries from ETO.
  7.  
  8.     Written by: Matthew Xavier Mora    
  9.  
  10.     Copyright:    Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
  11.  
  12.                 You may incorporate this Apple sample source code into your program(s) without
  13.                 restriction. This Apple sample source code has been provided "AS IS" and the
  14.                 responsibility for its operation is yours. You are not permitted to redistribute
  15.                 this Apple sample source code as "Apple sample source code" after having made
  16.                 changes. If you're going to re-distribute the source, we require that you make
  17.                 it clear in the source that the code was descended from Apple sample source
  18.                 code, but that you've made changes.
  19.  
  20.     Change History (most recent first):
  21.                 8/3/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  22.                 06/11/97    mxm             Fixed the error -2538 by passing nil for the regID.
  23.                 04/15/97    mxm                Cleaned it up for the Dev CD
  24.                 03/28/97    mxm                Took out the MyFindSpaceInUnitTable routine. I wasn't using the 
  25.                                             InstallDriverFromFile correctly. HighestUnitNumber wasn't the problem.
  26.                                             That's what I get for trying to program without the Documentation.
  27.                                             Added Drag Manger and ODoOC support so you can drag a driver
  28.                                             into the window or on the application and it will load it.
  29.                                             Display more info from the driver.
  30.                 03/25/97    mxm               Moved to a real app
  31.                                             Fixed the can't load the library a second time bug.
  32.                                               I was using HighestUnitNumber to get the unit number to load.
  33.                                              I thought this call found the last used unit number. It
  34.                                              actually expanded the unit table to the max number of 
  35.                                             entries! I put in MyFindSpaceInUnitTable routine and use it instead.
  36.                                              Fix crashing Malph by moving it into an application shell. I don't 
  37.                                              know why it would cause Malph to crash.
  38.  
  39.     
  40.                 
  41.                 02/01/96    mxm                I wrote the first version in the "Writing PCI drivers" class. Got it to load
  42.                                             the sample driver I was writing. No real user interface
  43.                                             to speak of.
  44.                                             
  45. */
  46. //------------------------------------------------------------------
  47. #pragma mark Includes
  48. //------------------------------------------------------------------
  49.  
  50. #include <Devices.h>
  51. #include <NameRegistry.h>
  52. #include <StandardFile.h>
  53. #include <LowMem.h>
  54. #include <Dialogs.h>
  55. #include "SimpleApp.h"
  56. #include <stdio.h>
  57. #include <string.h>
  58. #include <TextUtils.h>
  59. #include <CodeFragments.h>
  60.  
  61. //------------------------------------------------------------------
  62. #pragma mark Prototypes
  63. //------------------------------------------------------------------
  64.  
  65. pascal    OSErr    FSpGetFullPath(const FSSpec *spec, short *fullPathLength, Handle *fullPath);
  66.  
  67. //------------------------------------------------------------------
  68. #pragma mark Globals
  69. //------------------------------------------------------------------
  70.  
  71. short    gDrvrRefNum = 0; /* global variable for storing my driver reference number */
  72. long     gLoadButton;
  73. long    gUnloadButton;
  74. short     gVert;
  75. short    gLineHeight;
  76. NMRec    gAlertNMRec;
  77. Str255    gAlertStr = "\pAn error occurred. Please bring Matt's PCI Loader to the front.";
  78. short    gError = 0;
  79.  
  80. //------------------------------------------------------------------
  81. #pragma mark Defines
  82. //------------------------------------------------------------------
  83.  
  84. #pragma mark -
  85.  
  86. //------------------------------------------------------------------
  87. static void AlertUser(short err)
  88. //------------------------------------------------------------------
  89. {
  90.     // in this case just set the global and the idle routine will display the error
  91.     gError = err;
  92. }
  93.  
  94. /*
  95. // I grabbed this code from somewhere
  96. //------------------------------------------------------------------
  97. static short MyFindSpaceInUnitTable(void)
  98. //------------------------------------------------------------------
  99. {
  100.     Ptr            curUTableBase, newUTableBase;
  101.     short            curUTableEntries, newUTableEntries;
  102.     short            refNum, unitNum;
  103.     
  104.     // get current unit table values from low memory globals 
  105.     curUTableEntries = LMGetUnitTableEntryCount();
  106.     curUTableBase     = LMGetUTableBase();
  107.     
  108.     // search for empty space in the current unit table 
  109.     for ( unitNum = curUTableEntries - 1; 
  110.             unitNum >= 48; // lowest available unit number 
  111.             unitNum-- )
  112.     {
  113.         refNum = ~(unitNum);
  114.         if (GetDCtlEntry(refNum) == nil)
  115.             return(unitNum); // found a space 
  116.     }
  117.     
  118.     
  119.     // no space in the current table, so make a new one 
  120.     
  121.     // increase the size of the table by 16 (an arbitrary value)
  122.     newUTableEntries = curUTableEntries + 16;
  123.     
  124.     // allocate space for the new table 
  125.     newUTableBase =  NewPtrSysClear((long)newUTableEntries * sizeof(Handle));
  126.     if (newUTableBase == nil) {
  127.         return(MemError());
  128.     }
  129.     // copy the old table to the new table 
  130.     BlockMoveData(curUTableBase, newUTableBase, (long)curUTableEntries * sizeof(Handle));
  131.     
  132.     // set the new unit table values in low memory 
  133.     LMSetUTableBase(newUTableBase);
  134.     LMSetUnitTableEntryCount( newUTableEntries);
  135.     
  136.     unitNum = newUTableEntries - 1;
  137.  
  138.     // unitNum = 0; //uh bad thing man.
  139.     return(unitNum); 
  140. }
  141.  
  142. */
  143.  
  144.  
  145. //------------------------------------------------------------------
  146. static void ForceUpdate(void)
  147. //------------------------------------------------------------------
  148. {
  149.     if (gSACurrentWindow) {
  150.         SetPort(gSACurrentWindow);
  151.         InvalRect(&gSACurrentWindow->portRect);
  152.     }    
  153. }
  154.  
  155. //------------------------------------------------------------------
  156. static void UnloadDriver(void)
  157. //------------------------------------------------------------------
  158. {
  159.     short err;
  160.     
  161.     if (gDrvrRefNum) { 
  162.         err = RemoveDriver(gDrvrRefNum, true);
  163.         gDrvrRefNum = 0;
  164.     }
  165. }
  166.  
  167. //------------------------------------------------------------------
  168. static short InstallDriver(FSSpecPtr spec) 
  169. //------------------------------------------------------------------
  170. {
  171.     RegEntryID             device={0,0};
  172.     short                 lowUnitNumber,hiUnitNumber ;    
  173.     short                 err = -1;    
  174.         
  175.     
  176.     if (gDrvrRefNum) {
  177.         UnloadDriver();
  178.     }
  179.      lowUnitNumber = 48 ; // MyFindSpaceInUnitTable();
  180.      hiUnitNumber = HighestUnitNumber();
  181.      
  182.     if (lowUnitNumber > 0) {
  183.     
  184.         err = InstallDriverFromFile(spec,nil,lowUnitNumber ,hiUnitNumber,&gDrvrRefNum);
  185.         if (err != noErr) {
  186.             AlertUser(err);  // we can be called from inside a drag handler so just set a flag
  187.             SAEnableObject(gLoadButton);
  188.             SADisableObject(gUnloadButton);
  189.         } else {
  190.             SAEnableObject(gUnloadButton);
  191.             SADisableObject(gLoadButton);
  192.         }
  193.     } 
  194.     ForceUpdate();
  195.     return err;    
  196. }
  197.  
  198. // Load a driver via StandardFile
  199. //------------------------------------------------------------------
  200. static    short LoadDriver(void)
  201. //------------------------------------------------------------------
  202. {
  203.  
  204.     short                 err = -1;
  205.  
  206.     OSType                 typeList[4];
  207.     OSType *            typeListPtr = typeList;
  208.     StandardFileReply     reply;
  209.  
  210.     
  211.     typeList[0] = 'ndrv';
  212.         
  213.     StandardGetFile(nil,1,typeList,&reply);
  214.     if (reply.sfGood) {
  215.         err = InstallDriver(&reply.sfFile);
  216.     }
  217.     
  218.     return err;    
  219. }
  220.  
  221. // ODOC handler
  222. //------------------------------------------------------------------
  223. static pascal OSErr     MyOpenFileProc(FSSpecPtr myFSSPtr)
  224. //------------------------------------------------------------------
  225. {
  226.     short err;
  227.     
  228.     err =  InstallDriver(myFSSPtr) ;
  229.     return noErr;
  230. }
  231.  
  232.  
  233. //------------------------------------------------------------------
  234. static    pascal short DoIdle(EventRecord *evt)
  235. //------------------------------------------------------------------
  236. {
  237.         Str255 tempStr;    
  238.         short err;
  239. #pragma unused (evt)
  240.     // in case we want to do something at idle time
  241.     
  242.     if (gError) {
  243.         gAlertNMRec.qType         = nmType;
  244.         gAlertNMRec.nmFlags        = 0;
  245.         gAlertNMRec.nmPrivate    = 0;
  246.         gAlertNMRec.nmReserved    = 0;
  247.         gAlertNMRec.nmResp         = nil;
  248.         gAlertNMRec.nmStr         = gAlertStr;
  249.         gAlertNMRec.nmSound     = nil;
  250.         gAlertNMRec.nmMark         = 1;
  251.         gAlertNMRec.nmIcon         = nil;
  252.         err = AEInteractWithUser(kAEDefaultTimeout,&gAlertNMRec,nil);    
  253.         
  254.         NumToString(gError,tempStr);
  255.         ParamText(tempStr,"\p","\p","\p");
  256.         Alert(1002,nil);
  257.         gError = 0;
  258.     }
  259.     return noErr;
  260. }
  261.  
  262. //------------------------------------------------------------------
  263.     static    pascal short DoLoadDriver(ButtonItemRef me,long refCon)
  264. //------------------------------------------------------------------
  265. {
  266. #pragma unused (me,refCon)
  267.     short err;
  268.     
  269.     err = LoadDriver();
  270.     if (err == noErr ) {
  271.         SADisableMe();
  272.         SAEnableObject(gUnloadButton);
  273.         ForceUpdate();
  274.     }
  275.     return noErr;
  276. }
  277.  
  278. //------------------------------------------------------------------
  279.     static    pascal short DoUnloadDriver(ButtonItemRef me,long refCon)
  280. //------------------------------------------------------------------
  281. {
  282. #pragma unused (me,refCon)
  283.  
  284.     UnloadDriver();
  285.     SADisableMe();
  286.     SAEnableObject(gLoadButton);
  287.     ForceUpdate();
  288.     
  289.     return noErr;
  290. }
  291.  
  292. //------------------------------------------------------------------
  293.     static GetLineHeight(void)
  294. //------------------------------------------------------------------
  295. {
  296.     FontInfo info;
  297.     
  298.     GetFontInfo(&info);
  299.     return (info.ascent + info.descent + info.leading);
  300. }
  301.  
  302. //------------------------------------------------------------------
  303.     static void DrawItem(StringPtr label,StringPtr text)
  304. //------------------------------------------------------------------
  305. {
  306.         DrawString (label);
  307.         DrawString (text);
  308.         MoveTo(5,gVert);
  309.         gVert += gLineHeight; 
  310. }
  311.  
  312. //------------------------------------------------------------------
  313.     static void DrawHex(StringPtr label,long n)
  314. //------------------------------------------------------------------
  315. {
  316.         char s[256];
  317.         
  318.         sprintf(s,"%0X",n);
  319.         DrawString (label);
  320.         DrawText(s,0,strlen(s));
  321.         MoveTo(5,gVert);
  322.         gVert += gLineHeight; 
  323. }
  324.  
  325. //------------------------------------------------------------------
  326.     static void DrawHandle(StringPtr label,Handle text)
  327. //------------------------------------------------------------------
  328. {
  329.     DrawString (label);
  330.     if (text) {
  331.         DrawText (*text,0,GetHandleSize(text));
  332.     }
  333.     MoveTo(5,gVert);
  334.     gVert += gLineHeight; 
  335. }
  336.  
  337. //------------------------------------------------------------------
  338.     static void DrawNumber(StringPtr label,long n)
  339. //------------------------------------------------------------------
  340. {    
  341.     Str255 tempStr;
  342.  
  343.     NumToString(n,tempStr);
  344.     DrawString (label);
  345.     DrawString (tempStr);
  346.     MoveTo(5,gVert);
  347.     gVert += gLineHeight; 
  348. }
  349.  
  350. //------------------------------------------------------------------
  351.     static    pascal short MyUpdate(long refCon)
  352. //------------------------------------------------------------------
  353. {
  354. #pragma unused (refCon)
  355.     Str255                 tempStr;
  356.     UnitNumber             unitNum;
  357.     DriverFlags         flags;
  358.     DriverOpenCount     count;
  359.     RegEntryID             device;
  360.     CFragSystem7Locator    driverLoadLocation;
  361.     CFragConnectionID     fragmentConnID;
  362.     DriverEntryPointPtr fragmentMain;
  363.     DriverDescription     driverDesc;
  364.     FSSpec                fileSpec;
  365.     Handle                 fullPath = nil;
  366.     short                 err    = 0;
  367.     short                fullPathLength;
  368.     
  369.     gLineHeight = GetLineHeight();
  370.     
  371.     gVert = 120;
  372.     MoveTo(5,gVert);
  373.     gVert += gLineHeight; 
  374.     
  375.     if (gDrvrRefNum) {
  376.     
  377.         DrawString("\pThe driver is loaded. refNum = (");
  378.         NumToString(gDrvrRefNum,tempStr);
  379.         DrawString (tempStr);
  380.         DrawString("\p)");
  381.         MoveTo(5,gVert);
  382.         
  383.         gVert += gLineHeight; 
  384.         driverLoadLocation.u.onDisk.fileSpec = &fileSpec;
  385.         err =  GetDriverInformation(gDrvrRefNum,
  386.                                     &unitNum, 
  387.                                     &flags, 
  388.                                     &count,
  389.                                     tempStr, 
  390.                                     &device,
  391.                                     &driverLoadLocation,
  392.                                     &fragmentConnID,
  393.                                     &fragmentMain, 
  394.                                     &driverDesc);
  395.         
  396.         DrawItem("\pName: ",tempStr);
  397.         DrawNumber("\pUnitNumber: ",unitNum);    
  398.         DrawNumber("\pCount: ",count);
  399.         DrawHex("\pflags: ",flags);
  400.  
  401.         err = FSpGetFullPath(&fileSpec,&fullPathLength, &fullPath);
  402.         if (fullPath) {
  403.             DrawHandle("\pPath: ",fullPath);
  404.             DisposeHandle(fullPath);
  405.         }    
  406.         DrawHex("\pFragment Main: 0x",(long)fragmentMain);        
  407.     } else {
  408.         DrawString("\pNo Driver Loaded.             ");
  409.     }
  410.     
  411.     return noErr;
  412. }
  413.  
  414. //---------------------------------------------------------------------------------------
  415.     static pascal OSErr MyPutData (ObjectItemRef orh,OSType kind,Ptr  data,long len,long flags)
  416. //---------------------------------------------------------------------------------------
  417. {
  418. #pragma unused (orh,len,flags)
  419.  
  420.     HFSFlavor * theFile;
  421.     
  422.     if (kind == flavorTypeHFS) { 
  423.         theFile = (HFSFlavor *)data;
  424.         
  425.         if (theFile->fileType == 'cfrg' ) {
  426.             InstallDriver(&theFile->fileSpec);
  427.         }
  428.     }
  429.  
  430.  
  431.     return noErr;
  432. }
  433.  
  434.  
  435. // The drag receive handler
  436. //------------------------------------------------------------------
  437. static pascal short MyReceive(ObjectItemRef orh,DragReference theDrag)
  438. //------------------------------------------------------------------
  439. {
  440. #pragma unused(orh)
  441.     ItemReference    itemRef;
  442.     Size            dataSize;
  443.     HFSFlavor        theHFSFlavor;
  444.     OSErr            retCode;
  445.  
  446.  
  447.     // There is only one item, so get its reference number.
  448.     retCode = GetDragItemReferenceNumber(theDrag, 1, &itemRef);
  449.     
  450.     if (retCode == noErr) {
  451.         dataSize = sizeof(HFSFlavor);
  452.         retCode = GetFlavorData(theDrag, itemRef, flavorTypeHFS, &theHFSFlavor, &dataSize, 0);
  453.         if (retCode == noErr)  {
  454.             InstallDriver(&theHFSFlavor.fileSpec) ;
  455.         }
  456.  
  457.     }
  458.     return retCode;
  459. }
  460.  
  461. //------------------------------------------------------------------
  462. void main(void)
  463. //------------------------------------------------------------------
  464.     long     buttonID     = 1;
  465.     long     textID         = 2;
  466.     long    dragID         = 3;
  467.     Str255     tempStr;
  468.     Rect    r ;
  469.     long     gMyWindowID;
  470.     short    err;
  471.     
  472.     InitSimpleApp(2,kUseStandardMenu);      // Simple App Sets up the Tool Box For us 
  473.     gMyWindowID = GetDocumentWindow (128);     // Get our stored window 
  474.     SetOpenFileProc (MyOpenFileProc);        // set open file proc. This is called on an ODOC event
  475.     
  476.     SetWTitle(gSACurrentWindow,"\pMatt's PCI Driver Loader");
  477.     
  478.     InstallIdleProc(DoIdle);
  479.     SetWindowUpdateProc(gSACurrentWindow,MyUpdate );     //gSACurrentWindow for now, its a Kludge
  480.     GetIndString(tempStr,kStaticStrings,kButtonName);    // Get button name
  481.  
  482.     SetRectDimensions(&r, 180, 20);            // This Sets its size without changing it position
  483.     SetRectLocation(&r, 10, 30);            // This Sets a rects anchor point
  484.     (void)InstallPushButton(&buttonID,gSACurrentWindow,tempStr,&r,0,DoLoadDriver,nil);
  485.     gLoadButton = buttonID;
  486.     OffsetRect(&r,200,0);
  487.     GetIndString(tempStr,kStaticStrings,3);    // Get button name
  488.     (void)InstallPushButton(&buttonID,gSACurrentWindow,tempStr,&r,0,DoUnloadDriver,nil);
  489.     gUnloadButton = buttonID;
  490.     SADisableMe();
  491.     
  492.     
  493.     SetRect(&r,4,55,gSACurrentWindow->portRect.right - 4,110);        
  494.     GetIndString(tempStr,kStaticStrings,kAboutText);    // Get about this snippet text
  495.     (void)InstallStaticText(&textID,gSACurrentWindow,tempStr,&r);    
  496.     
  497.     // lets add drag and drop support for our window    
  498.     err = InstallDragObject(&dragID,gSACurrentWindow,"\p",&gSACurrentWindow->portRect, nil, nil, MyReceive, 0);
  499.     err = SAInstallStandardDragHandlers(gSACurrentWindow);              // enable dragging
  500.     err = SAAddWindowDragDataTypes(gSACurrentWindow,flavorTypeHFS);        // we accept flavorTypeHFS
  501.  
  502.     Run();                                                                 //Let SimpleApp handle the rest
  503.         
  504.     // lets check and see if the driver is still loaded and ask the 
  505.     // user what to do if it is loaded
  506.     if (gDrvrRefNum) {
  507.         short itemHit;
  508.  
  509.         itemHit = Alert(1001,nil);
  510.         if (itemHit == 1 ) {
  511.             UnloadDriver();
  512.         }
  513.     }
  514. }
  515.  
  516.